#include <iostream>
#include <cstdlib>
#include <cstring>
#include <curses.h>
#include "window.h"

Curses_Window::Curses_Window(Map *map)
{
	MAP = map;
	QUIT = false;
	
	// Initialize ncurses windows
	initscr();
	keypad(stdscr, true);
	nonl();
	cbreak();
	noecho();
	
	// Create the windows
//	GAME =    newwin(50, 50, 10, 10);
//	STATUS =  newwin(50, 20, 10, 70);
//	MESSAGE = newwin(10, 50,  0, 10);  
}

Curses_Window::~Curses_Window()
{
	QUIT = true;
	MAP = NULL;
	delwin(GAME);
	delwin(STATUS);
	delwin(MESSAGE);
	endwin();
}

void Curses_Window::display(Creature *p)
{
	wrefresh(stdscr);					// This must me called first, or the screen will remain blank until
								// the user has pressed a key.
	// Display the game map
//	MAP->set(p);
	MAP->refresh();
	GAME = newwin(50, 50, 5, 0);
	for (int i=0; i<MAP->height(); i++)
	{
		for (int j=0; j<MAP->width(); j++)
		{
//			mvwaddch(GAME, i, j, MAP->display(j, i)->symbol());
			mvwaddch(GAME, i, j, MAP->display(j, i));
		}
	}
	wrefresh(GAME);
	
	// Display the status screen.
	STATUS =  newwin(50, 30, 5, 60);
	char *cstr = new char [p->name().size()+1];		// This is an ugly hack to get around C++'s inability
	strcpy(cstr, p->name().c_str());			// to pass a non-POD data type to a variadic function.
	mvwprintw(STATUS, 0, 0, "Name:\t\t%s", cstr);		// You are not expected to understand this.
	delete cstr;
	mvwprintw(STATUS, 1, 0, "Location:\t%d %d", p->x(), p->y());
	mvwprintw(STATUS, 2, 0, "Hitpoints:\t%d/%d", p->currentHitpoints(), p->maximumHitpoints());
	mvwprintw(STATUS, 3, 0, "Energy:\t\t%d/%d", p->currentEnergy(), p->maximumEnergy());
	mvwprintw(STATUS, 4, 0, "Strength:\t%d/%d", p->currentStrength(), p->maximumStrength());
	mvwprintw(STATUS, 5, 0, "Dexterity:\t%d/%d", p->currentDexterity(), p->maximumDexterity());
	mvwprintw(STATUS, 6, 0, "Constitution:\t%d/%d", p->currentConstitution(), p->maximumConstitution());
	wrefresh(STATUS);
	
	// Make sure to update the windows.
//	wrefresh(GAME); 			
//	wrefresh(STATUS);
//	wrefresh(MESSAGE);
//	refresh();
}

void Curses_Window::processInput(Creature *p)
{
		int x = p->x();
		int y = p->y();
		
		int input = getch();	// ncurses function
		switch(input)
		{
			case 'h':
				if (MAP->isBlocked(x-1,y))
					p->move(x-1,y,0);
				break;
			case 'j':
				if (MAP->isBlocked(x,y+1))
					p->move(x,y+1,0);
				break;
			case 'k':
				if (MAP->isBlocked(x,y-1))
					p->move(x,y-1,0);
				break;
			case 'l':
				if (MAP->isBlocked(x+1,y))
					p->move(x+1,y,0);
				break;
			case 'y':
				if (MAP->isBlocked(x-1,y-1))
					p->move(x-1,y-1,0);
				break;
			case 'u':
				if (MAP->isBlocked(x+1,y-1))
					p->move(x+1,y-1,0);
				break;
			case 'b':
				if (MAP->isBlocked(x-1,y+1))
					p->move(x-1,y+1,0);
				break;
			case 'n':
				if (MAP->isBlocked(x+1,y+1))
					p->move(x+1,y+1,0);
				break;
			case 'q':
				QUIT = true;
				break;
			case '4':
				if (MAP->isBlocked(x-1,y))
					p->move(x-1,y,0);
				break;
			case '2':
				if (MAP->isBlocked(x,y+1))
					p->move(x,y+1,0);
				break;
			case '8':
				if (MAP->isBlocked(x,y-1))
					p->move(x,y-1,0);
				break;
			case '6':
				if (MAP->isBlocked(x+1,y))
					p->move(x+1,y,0);
				break;
			case '7':
				if (MAP->isBlocked(x-1,y-1))
					p->move(x-1,y-1,0);
				break;
			case '9':
				if (MAP->isBlocked(x+1,y-1))
					p->move(x+1,y-1,0);
				break;
			case '1':
				if (MAP->isBlocked(x-1,y+1))
					p->move(x-1,y+1,0);
				break;
			case '3':
				if (MAP->isBlocked(x+1,y+1))
					p->move(x+1,y+1,0);
				break;
			case KEY_LEFT:
				if (MAP->isBlocked(x-1,y))
					p->move(x-1,y,0);
				break;
			case KEY_DOWN:
				if (MAP->isBlocked(x,y+1))
					p->move(x,y+1,0);
				break;
			case KEY_UP:
				if (MAP->isBlocked(x,y-1))
					p->move(x,y-1,0);
				break;
			case KEY_RIGHT:
				if (MAP->isBlocked(x+1,y))
					p->move(x+1,y,0);
				break;
			case KEY_HOME:
				if (MAP->isBlocked(x-1,y-1))
					p->move(x-1,y-1,0);
				break;
			case KEY_PPAGE:
				if (MAP->isBlocked(x+1,y-1))
					p->move(x+1,y-1,0);
				break;
			case KEY_END:
				if (MAP->isBlocked(x-1,y+1))
					p->move(x-1,y+1,0);
				break;
			case KEY_NPAGE:
				if (MAP->isBlocked(x+1,y+1))
					p->move(x+1,y+1,0);
				break;
			default:
				break;
		}
}

bool Curses_Window::quitGame()
{
	return QUIT;
}
